package com.cap.bts.framework.workbench.userlogin.controller;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.cap.bts.commonfunc.cache.service.IResetCacheService;
import com.cap.bts.commonfunc.common.constant.OperationType;
import com.cap.bts.commonfunc.common.util.UserUtil;
import com.cap.bts.commonfunc.ge.dealer.service.IDealerService;
import com.cap.bts.crmdp.dealer.card.util.FileUtil;
import com.cap.bts.crmdp.dealer.masterdata.dao.IMaintainDealerDao;
import com.cap.bts.crmdp.dealer.masterdata.domain.MasterDataDealerInfo;
import com.cap.bts.crmdp.dealer.masterdata.service.IMaintainDealerService;
import com.cap.bts.framework.auth.constant.AuthConstant;
import com.cap.bts.framework.auth.filter.SSOAuthInterceptor;
import com.cap.bts.framework.auth.util.SSOConfigurations;
import com.cap.bts.framework.auth.util.UserAuthenticationUtils;
import com.cap.bts.framework.bizlog.domain.BizLog;
import com.cap.bts.framework.bizlog.service.IBizLoggerService;
import com.cap.bts.framework.codemapping.service.ICodeMapping;
import com.cap.bts.framework.common.constant.CommonErrorConstants;
import com.cap.bts.framework.common.exception.AppException;
import com.cap.bts.framework.common.util.CookieUtils;
import com.cap.bts.framework.common.util.Utils;
import com.cap.bts.framework.mailservice.utils.PropertiesUtil;
import com.cap.bts.framework.usermgnt.constant.AccountStatus;
import com.cap.bts.framework.usermgnt.constant.UserType;
import com.cap.bts.framework.usermgnt.domain.User;
import com.cap.bts.framework.usermgnt.service.IEmployeeInfoService;
import com.cap.bts.framework.usermgnt.service.IUserMgntService;
import com.cap.bts.framework.usermgnt.util.PasswordUtil;
import com.cap.bts.framework.workbench.constant.WorkbenchConstant;
import com.cap.bts.framework.workbench.userlogin.dto.LoginDto;
import com.cap.bts.framework.workbench.userlogin.dto.OperationPwdDto;
import com.cap.bts.framework.workbench.userlogin.service.IUserService;

@Controller
@RequestMapping(value = "/login")
public class LoginRestController {
	private static Logger logger = Logger.getLogger(LoginRestController.class);

	@Autowired
	private IUserMgntService userService;
	@Autowired
	private IUserService userServiceLoca;
	@Autowired
	private ICodeMapping codeMappingService;
	@Autowired
	private IBizLoggerService bizloggerService;

	@Autowired
	private IEmployeeInfoService employeeInfoService;

	@Resource(name = "dealerService")
	private IDealerService dealerService;
	@Resource(name = "resetCacheService")
	private IResetCacheService resetCacheService;
	@Autowired
	private IMaintainDealerService maintainDealerService;
	@Autowired
	IMaintainDealerDao maintainDealerDao;

	@RequestMapping(method = RequestMethod.GET)
	public String login(Model model) {
		model.addAttribute("loginDto", new LoginDto());
		return WorkbenchConstant.LOGIN_PAGE;
	}

	@RequestMapping(method = RequestMethod.POST)
	public String processLogin(LoginDto loginDto, BindingResult result,
			Model model, HttpServletRequest request,
			HttpServletResponse response) throws AppException

	{
		

		User actualUser = null;

		if (loginDto != null) {
			if (!Utils.notEmpty(loginDto.getUserCode())) {
				result.rejectValue("errorMsg",
						WorkbenchConstant.NOTEMPTY_LOGINDTO_NAME);
				model.addAttribute("loginDto", loginDto);
				return WorkbenchConstant.LOGIN_PAGE;
			}
			if (!Utils.notEmpty(loginDto.getPasswd())) {
				result.rejectValue("errorMsg",
						WorkbenchConstant.NOTEMPTY_LOGINDTO_PASSWD);
				model.addAttribute("loginDto", loginDto);
				return WorkbenchConstant.LOGIN_PAGE;
			}
			// if(loginDto.getPasswd().trim().length()<UserMgntConstants.MIN_PASSWORD
			// ||
			// loginDto.getPasswd().trim().length()>UserMgntConstants.MAX_PASSWORD){
			// result.rejectValue("errorMsg",
			// WorkbenchConstant.DTO_VALIDATOR_LENGTH,
			// new Object[] {
			// UserMgntConstants.MIN_PASSWORD,UserMgntConstants.MAX_PASSWORD },
			// null);
			// model.addAttribute("loginDto", loginDto);
			// return WorkbenchConstant.LOGIN_PAGE;
			// }
			actualUser = userService.getUserByUserCode(loginDto.getUserCode());
			if (actualUser != null && actualUser.getPassword() != null) {
				if (actualUser.getUserType() == UserType.CENTRAL) {
					// user lock
					result.rejectValue("errorMsg",
							WorkbenchConstant.NAME_PWD_ERROR_KEY);
					model.addAttribute("loginDto", loginDto);
					return WorkbenchConstant.LOGIN_PAGE;
				}
				if (actualUser.getIsLocked() == AccountStatus.LOCK.getValue()) {
					// user lock
					result.rejectValue("errorMsg",
							WorkbenchConstant.ACCOUNT_LOCK);
					loginDto.setPasswd("");
					model.addAttribute("loginDto", loginDto);
					return WorkbenchConstant.LOGIN_PAGE;
				}
				// boolean expired = userService.isAccountExpired(actualUser);
				// if (expired) {
				// // account expired
				// result.rejectValue("errorMsg",
				// WorkbenchConstant.ACCOUNT_EXPIRE);
				// loginDto.setPasswd("");
				// model.addAttribute("loginDto", loginDto);
				// // lock account
				// userServiceLoca.lockDealerAccount(actualUser);
				// return WorkbenchConstant.LOGIN_PAGE;
				// }
				// if(getIsUpdatePwd(actualUser)){//密码没有修改过期
				// result.rejectValue("errorMsg",
				// WorkbenchConstant.PASSWORD_NOT_UPDATE);
				// loginDto.setPasswd("");
				// userServiceLoca.lockDealerAccount(actualUser);
				// model.addAttribute("loginDto", loginDto);
				// return WorkbenchConstant.LOGIN_PAGE;
				// }
				// if(actualUser.getStatusCode()==UserStatus.INACTIVE){
				// // user lock
				// result.rejectValue("errorMsg",
				// WorkbenchConstant.USER_STATUS_NOT_ACTIVE);
				// loginDto.setPasswd("");
				// model.addAttribute("loginDto", loginDto);
				// return WorkbenchConstant.LOGIN_PAGE;
				// }
				String decryptedPwd = PasswordUtil.decodePassword(actualUser
						.getPassword());
				if (!decryptedPwd.equals(loginDto.getPasswd())) {
					// password incorrect,add times
					if (actualUser.getLoginFailedTimes() > 8) {
						actualUser.setLoginFailedTimes(8);
					}
					User user = userService.recordFailedTimes(actualUser);
					// password error
					// if (user.getLoginFailedTimes() >=
					// UserMgntConstants.MAX_PASSWORD_INCORRECT_TIME) {
					// // lock user
					// userServiceLoca.lockDealerAccount(actualUser);
					// result.rejectValue("errorMsg",
					// WorkbenchConstant.PASSWORD_MAX_CORRECT);
					// loginDto.setPasswd("");
					// model.addAttribute(loginDto);
					// return WorkbenchConstant.LOGIN_PAGE;
					// }
					// set correct times
					userService.setUserLoginTime(actualUser);
					result.rejectValue("errorMsg",
							WorkbenchConstant.PASSWORD_CORRECT_TIMES,
							new Object[] { actualUser.getLoginFailedTimes() },
							null);
					loginDto.setPasswd("");
					model.addAttribute(loginDto);
					return WorkbenchConstant.LOGIN_PAGE;
				}

				/**
				 * 若该用户对应的经销商已停业，则不允许登录。
				 */
				// DealerInfo dealer =
				// dealerService.getDealerInfoByUserId(actualUser.getId());
				// if(dealer != null){
				// if(dealer.getDealerStatus() != null &&
				// DealerStatus.SHUTDOWN.getValue().equals(dealer.getDealerStatus())){
				// result.rejectValue("errorMsg",
				// WorkbenchConstant.USER_ACCOUNT_FORBIDDEN);
				// loginDto.setPasswd("");
				// model.addAttribute("loginDto", loginDto);
				// return WorkbenchConstant.LOGIN_PAGE;
				// }
				// }else{
				// result.rejectValue("errorMsg",
				// WorkbenchConstant.USER_ACCOUNT_FORBIDDEN);
				// loginDto.setPasswd("");
				// model.addAttribute("loginDto", loginDto);
				// return WorkbenchConstant.LOGIN_PAGE;
				// }

				// reset failed times
				userService.resetFailedTimes(actualUser);
				userService.setUserLoginTime(actualUser);

				StringBuffer sb = request.getRequestURL();
				logger.debug("user login string" + sb);

				String uriString = (String) request.getSession().getAttribute(
						WorkbenchConstant.URI_STRING);
				String queryString = (String) request.getSession()
						.getAttribute(WorkbenchConstant.QUERY_STRING);

				String URL = (String) request.getSession().getAttribute(
						WorkbenchConstant.PREVIOUS_URL);

				logger.debug("uri in server " + uriString);
				logger.debug("queryString in server " + queryString);

				// if session store the uri string,forward to the uri
				if (StringUtils.isNotBlank(URL)) {
					request.setAttribute("contentUrl", URL);
					request.getSession().removeAttribute(
							WorkbenchConstant.PREVIOUS_URL);

				} else {
					request.setAttribute("contentUrl", "content");
				}
				// If different user login in one session, expire the previous
				// one.
				// UserAuthenticationUtils.checkDiffUserInOneSession(request,
				// actualUser.getUserCode());
				// Get new session
				// request.getSession(true).setAttribute("userSession",
				// actualUser);
				if (null == request.getSession(true).getAttribute("userSession")) {
					request.getSession(true).setAttribute("userSession",
							actualUser);
				} else {
					User user = (User) request.getSession(true).getAttribute("userSession");
//					if (!user.getUserCode().equals(loginDto.getUserCode())) {
					if (!StringUtils.equals(user.getUserCode(), loginDto.getUserCode())) {
						result.rejectValue("errorMsg",
								WorkbenchConstant.EXIST_USER_ACCOUNT);
						return WorkbenchConstant.LOGIN_PAGE;
					}
				}

				UserAuthenticationUtils.setLoginToCookie(request, response,
						actualUser.getUserCode());
				MasterDataDealerInfo dealerDto = maintainDealerDao
						.findById(actualUser.getDealerId());
				if (dealerDto != null) {
					actualUser.setDealerId(Long.valueOf(dealerDto.getId()));
				}
				// Store Current Login user
				UserUtil.setCurrentUser(actualUser);
				// return CmsConstant.INEX_PAGE;
				// EmployeeInfo employeeInfo =
				// employeeInfoService.getEmployeeInfoById(actualUser.getEmployeeId());
				// if(employeeInfo != null){
				// Integer canExport = employeeInfo.getExportData();
				// UserAuthenticationUtils.setCookie(request, response,
				// canExport+"");
				// }
				// Reset cache
				resetCacheService.resetDealerCacheByUserId(actualUser.getId());
				// Logging User Operation to BizLog
				if (actualUser != null) {
					try {
						BizLog userLog = new BizLog();
						userLog.setUserName(actualUser.getUserCode());
						userLog.setOperationType(OperationType.LOGIN_OPERATION
								.getValue());
						userLog.setOperationDesc(actualUser.getUserCode() + " "
								+ OperationType.LOGIN_OPERATION.getValue());
						userLog.setOperationTime(new Date());
						userLog.setCreateBy(actualUser.getId());
						bizloggerService.log(userLog);
					} catch (Exception e) {
						logger.error(e);
					}
				}
				/**
				 * If this user has login in on another client, force invalid
				 * the session on another client. Added by GuYiFeng
				 */
				UserAuthenticationUtils.setSessionIdToCookie(request, response);
				UserAuthenticationUtils.checkLoginUserSession(request,
						actualUser.getUserCode());

				try {
					response.sendRedirect("/crm/buildMenu");

				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				return null;
				// return "http://localhost:8089/crm/buildMenu";
				// return "redirect:/buildMenu";
			} else {
				// name and password is wrong, go to login page and show the
				// error msg.
				result.rejectValue("errorMsg",
						WorkbenchConstant.NAME_PWD_ERROR_KEY);
				loginDto.setPasswd("");
				model.addAttribute("loginDto", loginDto);
				return WorkbenchConstant.LOGIN_PAGE;
			}
		} else {
			return WorkbenchConstant.INEX_PAGE;
		}
		// check if the name and passWowd is correct.
		/*
		 * if (actualUser S!= null && actualUser.getPassword() != null &&
		 * actualUser.getPassword().equals(loginDto.getPasswd())) { StringBuffer
		 * sb = request.getRequestURL(); logger.debug("user login string" + sb);
		 * 
		 * UserAuthenticationUtils.setLoginToCookie(request, response,
		 * actualUser.getName()); S String uriString = (String)
		 * request.getSession().getAttribute(CmsConstant.URI_STRING); String
		 * queryString = (String) request.getSession().getAttribute(
		 * CmsConstant.QUERY_STRING);
		 * 
		 * String URL = (String)
		 * request.getSession().getAttribute(CmsConstant.PREVIOUS_URL);
		 * 
		 * logger.debug("uri in server " + uriString);
		 * logger.debug("queryString in server " + queryString);
		 * 
		 * // if session store the uri string,forward to the uri if
		 * (StringUtils.isNotBlank(URL)) { request.setAttribute("contentUrl",
		 * URL); request.getSession().removeAttribute(CmsConstant.PREVIOUS_URL);
		 * 
		 * } else { request.setAttribute("contentUrl", "content"); }
		 * request.getSession().setAttribute("userSession", actualUser);
		 * 
		 * return CmsConstant.INEX_PAGE; } else { // name and password is wrong,
		 * go to login page and show the error // msg.
		 * result.rejectValue("name", CmsConstant.NAME_PWD_ERROR_KEY);
		 * loginDto.setPasswd(""); model.addAttribute("loginDto", loginDto);
		 * return CmsConstant.LOGIN_PAGE; }
		 */

	}

	private boolean getIsUpdatePwd(User currUser) throws AppException {
		return true;
	}

	private int getDays(Date startDate, Date endDate) {
		if (endDate == null) {
			endDate = new Date();
		}
		Long start = startDate.getTime();
		Long end = endDate.getTime();
		Long quot = start - end;
		return (int) (quot / (1000 * 60 * 60 * 24));
	}

	@RequestMapping(value = "/resetForceLogoutFlag")
	public String resetForceLogoutFlag(Model model, HttpServletRequest request,
			HttpServletResponse response) {
		model.addAttribute("loginDto", new LoginDto());
		UserAuthenticationUtils.resetForceLogoutFlag(request, response);
		String domain = PropertiesUtil
				.getProperties(AuthConstant.DMS_DOMAIN_KEY);
		CookieUtils.setCookie(request, response, domain,
				AuthConstant.COOKIE_IS_FORCE_LOGOUT, "false", 0);
		return WorkbenchConstant.LOGIN_PAGE;
	}

	@RequestMapping(value = "/toPwdRequired")
	public String toPwdRequired(Model model) throws AppException {
		model.addAttribute("OperationPwdDto", new OperationPwdDto());
		return "workbench/operationpassword";
	}

	@RequestMapping(value = "/toOperationPwdForUpdateMobile")
	public String toOperationPwdForUpdateMobile(Model model)
			throws AppException {
		model.addAttribute("OperationPwdDto", new OperationPwdDto());
		return "workbench/operationpwdforupdatemobile";
	}

	/**
	 * 当用户为多门店时跳转至此页面进行门店选择 modify by Zach
	 * 
	 * @param model
	 * @param request
	 * @param response
	 * @return
	 * @throws AppException
	 */
	@RequestMapping(value = "/toSelectedOrgs")
	public String toSelectedOrgs(Model model, HttpServletRequest request,
			HttpServletResponse response) throws AppException {
		String ssoLoginOrgs = (String) request.getSession().getAttribute(
				SSOAuthInterceptor.SSO_LOGIN_ORGS);

		List<String> dearlerIds = new ArrayList<String>();
		if (ssoLoginOrgs != null) {
			String[] orgs = ssoLoginOrgs.split(",");
			if (orgs != null) {
				for (String temp : orgs) {
					dearlerIds.add(temp);
				}
			}
		}

		List<MasterDataDealerInfo> dealerInfos = maintainDealerService
				.getDearlerIntoByDealerIds(dearlerIds);
		model.addAttribute("dealerCodes", dealerInfos);
		return "workbench/selectedOrgs";

	}

	@RequestMapping(value = "/pwdRequired")
	@ResponseBody
	public OperationPwdDto pwdRequired(Model model, HttpServletRequest request,
			OperationPwdDto operationPwdDto) throws AppException {
		try {
			operationPwdDto.setDealerNum(request.getSession()
					.getAttribute("dealerNum").toString());
			MasterDataDealerInfo masterDataDealerInfo = maintainDealerService
					.getDealerByDealerNum(operationPwdDto.getDealerNum());
			if (masterDataDealerInfo != null) {
				if (maintainDealerService.getDealerByOperationPwdAndDealerNum(
						operationPwdDto.getOperationPassword(),
						operationPwdDto.getDealerNum())) {
					operationPwdDto.setVerifyOperationPwd(true);
					operationPwdDto.setUrl(request.getSession()
							.getAttribute("url").toString());
					request.getSession().setAttribute("operationPwdFlag", "1");
					if (masterDataDealerInfo.getLastOpreationPwdChangeTime() == null) {
						operationPwdDto.setFirstOperationPwd(true);
					} else {
						operationPwdDto.setFirstOperationPwd(false);
					}
				}
				;
			}
		} catch (Exception e) {
			logger.error(e);
			throw new AppException(CommonErrorConstants.SYSTEM_ERROR,
					e.getLocalizedMessage());
		}
		return operationPwdDto;
	}

	@RequestMapping(value = "/operationpasswordForUpdateMobile")
	@ResponseBody
	public OperationPwdDto operationpasswordForUpdateMobile(Model model,
			HttpServletRequest request, OperationPwdDto operationPwdDto)
			throws AppException {
		try {
			operationPwdDto.setDealerNum(Long.toString(UserUtil
					.getCurrentUser().getDealerId()));
			MasterDataDealerInfo masterDataDealerInfo = maintainDealerService
					.getDealerByDealerNum(operationPwdDto.getDealerNum());
			if (masterDataDealerInfo != null) {
				if (maintainDealerService.getDealerByOperationPwdAndDealerNum(
						operationPwdDto.getOperationPassword(),
						operationPwdDto.getDealerNum())) {
					operationPwdDto.setVerifyOperationPwd(true);
					if (masterDataDealerInfo.getLastOpreationPwdChangeTime() == null) {
						operationPwdDto.setFirstOperationPwd(true);
					} else {
						operationPwdDto.setFirstOperationPwd(false);
					}
				}
				;
			}
		} catch (Exception e) {
			logger.error(e);
			throw new AppException(CommonErrorConstants.SYSTEM_ERROR,
					e.getLocalizedMessage());
		}
		return operationPwdDto;
	}

	@RequestMapping(value = "/downloadFile")
	public void downloadFile(Model model, HttpServletRequest request,
			HttpServletResponse response) throws AppException {
		String path = request.getSession().getServletContext().getRealPath("/");
		File file = new File(path + "//WEB-INF//file//"
				+ "驰加会员管理平台用户操作手册.pdf");
		FileUtil.downloadFile(file, response, request);
	}

}
